package com.doyutu.seed.config.shiro;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.doyutu.seed.entity.StatPermissionUrl;
import com.doyutu.seed.entity.StatRolePermissionRel;
import com.doyutu.seed.entity.StatUser;
import com.doyutu.seed.entity.StatUserRoleRel;
import com.doyutu.seed.service.StatPermissionUrlService;
import com.doyutu.seed.service.StatRolePermissionRelService;
import com.doyutu.seed.service.StatUserRoleRelService;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.AntPathMatcher;

/**
 * @author DoyuTu
 * @version 0.0.1
 * spring-boot-project-seed
 */
public class UrlPermissionsFilter extends PermissionsAuthorizationFilter {

    @Autowired
    private StatUserRoleRelService statUserRoleRelService;

    @Autowired
    private StatRolePermissionRelService statRolePermissionRelService;

    @Autowired
    private StatPermissionUrlService statPermissionUrlService;

    @Override
    public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
        String curUrl = getRequestUrl(request);
        Subject subject = SecurityUtils.getSubject();
        if (subject.getPrincipal() == null || StringUtils.endsWithAny(curUrl, ".js", ".css", ".html")
                || StringUtils.endsWithAny(curUrl, ".jpg", ".png", ".gif", ".jpeg")
                || StringUtils.equals(curUrl, "/unauthor")) {
            return true;
        }
        StatUserRoleRel statUserRoleRel = statUserRoleRelService.getOne(new QueryWrapper<>(StatUserRoleRel.builder().userId(((StatUser) subject.getPrincipal()).getId()).build()));
        if (Objects.isNull(statUserRoleRel)) {
            return false;
        }
        StatRolePermissionRel statRolePermissionRel = statRolePermissionRelService.getOne(new QueryWrapper<>(StatRolePermissionRel.builder().roleId(statUserRoleRel.getRoleId()).build()));
        if (Objects.isNull(statRolePermissionRel)) {
            return false;
        }
        List<String> urls = Stream.of(statPermissionUrlService.getOne(new QueryWrapper<>(StatPermissionUrl.builder().id(statRolePermissionRel.getPermissionId()).build()))).map(StatPermissionUrl::getUrl).collect(Collectors.toList());
        AntPathMatcher pathMatcher = new AntPathMatcher();
        for (String url : urls) {
            if (pathMatcher.match(url, curUrl)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 获取当前URL+Parameter
     *
     * @param request 拦截请求request
     * @return 返回完整URL
     * @author lance
     * @since 2014年12月18日 下午3:09:26
     */
    private String getRequestUrl(ServletRequest request) {
        HttpServletRequest req = (HttpServletRequest) request;
        String queryString = req.getQueryString();

        queryString = StringUtils.isBlank(queryString) ? "" : "?" + queryString;
        return req.getRequestURI() + queryString;
    }

    public static void main(String[] args) {
        AntPathMatcher pathMatcher = new AntPathMatcher();
        System.out.println(pathMatcher.match("/**", "/app/index"));
    }
}
